package com.handler;

import com.AwsUtils;
import com.Config;
import com.Main;
import com.VerificationUtils;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.cloudfront.AmazonCloudFront;
import com.amazonaws.services.cloudfront.AmazonCloudFrontClientBuilder;
import com.amazonaws.services.cloudfront.model.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.LogFactory;

import java.util.List;

/**
 * 执行一次更新缓存
 */
public class InvalidationHandler extends BaseHandler<String> {

    private AmazonCloudFront amazonCloudFront;

    public InvalidationHandler() {
        super(null);
    }

    @Override
    public void execute() {
        //注意你只能有三个并发的失效; 失效似乎需要10-30分钟。
        if (StringUtils.isEmpty(Config.updatePath)) {
            String rootPath = packCmd.rootPath;
            if (StringUtils.isEmpty(rootPath)) { // 如果是null
                Config.updatePath = Config.DEFAULT_PATH;
            } else {
                Config.updatePath = (StringUtils.startsWith(rootPath, "/") ? "" : "/") + rootPath + (StringUtils.endsWith(rootPath, "/") ? "*" : "/*");
            }
        }

        System.out.println("初始化cloudfront...");
        // 初始化服务器
        amazonCloudFront = AmazonCloudFrontClientBuilder.standard()
                .withRegion(Regions.EU_CENTRAL_1)
                .withCredentials(AwsUtils.awsUtils.getCredentialsProvider())
                .build();
        if (StringUtils.isEmpty(packCmd.distributionId)) {
            getDistribution();
        }
        if (StringUtils.isAnyEmpty(packCmd.distributionId, Config.updatePath)) {
            System.err.println("无效的输入: distributionId = " + packCmd.distributionId + ", updatePath = " + Config.updatePath);
        } else {
            System.out.println("匹配成功: distributionId = " + packCmd.distributionId + ", updatePath = " + Config.updatePath);
            this.invalidation();
        }
    }

    /**
     * 根据已知桶名字去寻找id 如果未找到  则使用手动选择
     */
    private void getDistribution() {
        ListDistributionsResult distributions = amazonCloudFront.listDistributions(new ListDistributionsRequest());
        List<DistributionSummary> lists = distributions.getDistributionList().getItems();
        if (StringUtils.isEmpty(packCmd.bucketName)) {
            getDistribution(lists);
            return;
        }
        System.out.println("寻找桶名为 [" + packCmd.bucketName + "] 的失效服务器...");
        String name;
        String findName = null;
        // 查找更新id
        for (DistributionSummary distributionSummary : lists) {
            List<Origin> origins = distributionSummary.getOrigins().getItems();
            for (Origin origin : origins) {
                name = origin.getDomainName();
                name = StringUtils.substringBefore(name, ".");
                if (name.equals(packCmd.bucketName)) { // 是否找到桶
                    findName = name;
                    System.out.println("找到匹配桶名 = " + name + ", 桶源路径= " + origin.getDomainName());
                    break;
                }
            }
            if (StringUtils.isNotEmpty(findName)) {
                packCmd.distributionId = distributionSummary.getId();
                break;
            }
        }

        if (StringUtils.isEmpty(packCmd.distributionId)) {
            getDistribution(lists);
        }
    }

    private void getDistribution(List<DistributionSummary> lists) {
        System.out.println("选择失效服务器 ");
        DistributionSummary distributionSummary;
        for (int i = 0; i < lists.size(); i++) {
            distributionSummary = lists.get(i);
            System.out.println(i + " | " +
                    " | " + distributionSummary.getId() +
                    " | " + distributionSummary.getComment() +
                    " | " + distributionSummary.getDomainName()
                    + " | " + distributionSummary.getStatus());
        }
        String cmd = Main.getScanner().nextLine().trim();
        int disId;
        if (StringUtils.isNumeric(cmd) && (disId = Integer.parseInt(cmd)) < lists.size()) {
            packCmd.distributionId = lists.get(disId).getId();
            System.out.println("失效服务器 = " + lists.get(disId).getComment());
            System.out.println("输入失效路径 /*  /a/*  /a/d/c/ 默认 /* 多个失效路径用空格隔开(最多同时失效3个路径) ");
            cmd = Main.getScanner().nextLine().trim();
            if (StringUtils.isEmpty(cmd)) {
                System.err.println("无效的输入");
                getDistribution(lists);
                return;
            }
            Config.updatePath = cmd;
        } else {
            System.err.println("无效的输入");
            getDistribution(lists);
        }
    }

    private void invalidation() {
        String[] invalidations = Config.updatePath.split("\\s+");
        System.out.println("失效路径数量 = " + invalidations.length);
        Paths paths = new Paths().withItems(invalidations).withQuantity(invalidations.length);

        String callerReference = VerificationUtils.randomString(14);

//        System.out.println("callerReference = "+callerReference);

        InvalidationBatch invalidationBatch = new InvalidationBatch(paths, callerReference);

        CreateInvalidationRequest createInvalidationRequest =
                new CreateInvalidationRequest(packCmd.distributionId, invalidationBatch);

        CreateInvalidationResult result = amazonCloudFront.createInvalidation(createInvalidationRequest);
        System.out.println("Invalidation ID = " + result.getInvalidation().getId());

        while (true) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                LogFactory.getLog(getClass()).error(null, e);
            }

            GetInvalidationResult result1 = amazonCloudFront.getInvalidation(new GetInvalidationRequest(
                    packCmd.distributionId, result.getInvalidation().getId()));
            String status = result1.getInvalidation().getStatus();
            System.out.print("\r");
            System.out.print("%n% ");
            System.out.print(status);
            if (status.equals("Completed"))
                break;
        }

        System.out.println();
        System.out.println("失效操作完成!");

    }


}
